// 手写promise
class MyPromise {
  // 三种状态
  static pending = '待定的'
  static fulfilled = '成功的'
  static rejected = '失败的'

  constructor(fn) {
    // 初始化状态为待定
    this.status = MyPromise.pending
    // 结果为空
    this.result = null
    // 成功状态的异步方法列表
    this.resolveCallbacks = []
    // 失败的状态的异步方法列表
    this.rejectCallbacks = []

    // 捕获异常
    try {
      fn(this.resolve.bind(this), this.reject.bind(this))
    } catch (error) {
      this.reject(error)
    }
  }
  // 定义成功时调用的方法
  resolve(result) {
    setTimeout(() => {
      if (this.status === MyPromise.pending) {
        this.status = MyPromise.fulfilled
        this.result = result
        this.resolveCallbacks.forEach(callback => {
          callback(result)
        })
      }
    })
  }

  // 定义失败时调用的方法
  reject(error) {
    setTimeout(() => {
      if (this.status === MyPromise.pending) {
        this.status = MyPromise.rejected
        this.result = error
        this.rejectCallbacks.forEach(callback => {
          callback(error.message)
        })
      }
    })
  }

  // then方法
  then(onFulfild, onRejected) {
    return new MyPromise((resolve, reject) => {
      onFulfild = typeof onFulfild === 'function' ? onFulfild : () => {}
      onRejected = typeof onRejected === 'function' ? onRejected : () => {}
      // 状态待定时，保存回调函数到列表
      if (this.status === MyPromise.pending) {
        this.resolveCallbacks.push(onFulfild)
        this.rejectCallbacks.push(onRejected)
      }

      // 成功的状态执行的回调函数
      if (this.status === MyPromise.fulfilled) {
        // 异步调用
        setTimeout(() => {
          onFulfild(this.result)
        })
      }
      // 失败的状态执行的回调函数
      if (this.status === MyPromise.rejected) {
        // 异步调用
        setTimeout(() => {
          onRejected(this.result)
        })
      }
    })
  }
}

console.log('第1步')
let myPromise = new MyPromise((resolve, reject) => {
  console.log('第2步')
  setTimeout(() => {
    console.log('第3部')
    resolve('resolve')
    reject('reject')
    console.log('第4步')
  })
})

myPromise.then(res => console.log(res))
